import {Tag} from "./Tag";

export const enum PlayCardEvent{
    ON_SELECTED_CARD = "on_selected_card",
    ON_FRAME_SELECTED_CARD = "on_frame_selected_card",
    ON_CLEAR_ALL_CARD_UP = "on_clear_all_card_up",
}

const {ccclass, property} = cc._decorator;

@ccclass
export class PlayCardUI extends cc.Component {
    static getCardRes = function (card:number) {
        let color = ((card & 0xf0) >> 4).toString(16);
        let size = (card & 0x0f).toString(16);
        return "game/poker/"+color+size;
    };

    @property(cc.Node)
    touchArea = null;
    @property(cc.Node)
    cardsNode = null;
    @property(cc.Boolean)
    selfAdaption = false;

    cards:Array<cc.Node> = [];
    touchStartCard:cc.Node = null;
    touchEndCard:cc.Node = null;
    isTouching:boolean = false;//是否是触摸状态
    isTakeFirst:boolean = false;//是否是发牌阶段
    isAutoDownCard:boolean = true;//触摸其他区域，牌是否会自动下落
    onLoad(){
        this.cards = this.cardsNode.children;
        for(let i=0;i<this.cards.length;i++) {
            let card = this.cards[i];
            if(card.getComponent(Tag)==null){
                card.addComponent(Tag);
            }
        }
        this.setCards([]);
        if(this.touchArea){
            this.touchArea.on(cc.Node.EventType.TOUCH_START, this.onTouchStart,this);
            this.touchArea.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove,this);
            this.touchArea.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd,this);
            this.touchArea.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd,this);
        }
    }

    setVisible(visible:boolean){
        this.node.active = visible;
    }

    takeFirstCards(values:Array<number>){
        this.isTakeFirst = true;
        for(let i=0;i<values.length;i++){
            let subValues = values.slice(0,values.length-i)
            setTimeout(function () {
                this.setCards(subValues);
                if(subValues.length == values.length){
                    this.isTakeFirst = false;
                }
            }.bind(this),subValues.length*200)
        }
    }

    /**
     设置牌—牌重排列、立即显示(可用于打牌时出牌区)
     */
    setCards(values:Array<number>){
        if(this.cards.length<values.length){
            cc.error("设置牌失败,无法找到与牌值个数相符的容器,请检查cocos creator是否有足够的控件");
            return;
        }

        for(let i=0;i<this.cards.length;i++){
            let card = this.cards[i];
            if(i<values.length){
                card.getComponent(Tag).tag = values[i];
                card.y = 0;
                //card.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(cc.url.raw(PlayCardUI.getCardRes(values[i])));
                cc.resources.load(PlayCardUI.getCardRes(values[i]), cc.SpriteFrame, function (err, spriteFrame:cc.SpriteFrame) {
                    card.getComponent(cc.Sprite).spriteFrame = spriteFrame;
                });

                card.active = true;
                this.setCardEnable(card,true);
            }else {
                card.getComponent(Tag).tag = 0;
                card.y = 0;
                card.active = false;
            }
        }

        let layout = this.cardsNode.getComponent(cc.Layout);
        if(layout && values.length>0 && this.selfAdaption){
            let spacingX = Math.floor(-(this.cards[0].width * values.length - cc.winSize.width) / (values.length - 1));
            if(spacingX>-(this.cards[0].width/2)){
                layout.spacingX = -(this.cards[0].width/2);
            }else{
                layout.spacingX = spacingX;
            }
        }
    }

    getCards():Array<cc.Node>{
        return this.cards;
    }

    getUpCards():Array<cc.Node>{
        let up = [];
        for(let i=0;i<this.cards.length;i++){
            let card = this.cards[i];
            if(this.isCardUp(card) && card.active){
                up.push(card);
            }
        }
        return up;
    }

    getValue(card:cc.Node):number{
        return card.getComponent(Tag).tag&0x0ff;
    }

    getUpCardsValue():Array<number>{
        let up = [];
        for(let i=0;i<this.cards.length;i++){
            let card = this.cards[i];
            if(this.isCardUp(card) && card.active){
                up.push(this.getValue(card));
            }
        }
        return up;
    }

    /**
     * 使一组手牌弹起
     * @param {Array<number>} values
     * @param {boolean} up
     */
    setCardsUp(values:Array<number>,up:boolean){
        if(this.isTakeFirst) return;
        for(let i=0;i<values.length;i++){
            let value = values[i];
            let card = null;
            console.log(value);
            for(let j=this.cards.length-1;j>=0;j--){
                if(this.cards[j].active && this.isCardUp(this.cards[j])!=up && this.getValue(this.cards[j]) == value){
                    card = this.cards[j];
                    break;
                }
            }
            if(card){
                console.log("up");
                this.setCardUp(card,up);
            }
        }
    }

    setCardsHighlighted(startCard:cc.Node,flag:boolean)
    {
        if(flag){
            startCard.color = new cc.Color(120,120,120);
        }else{
            startCard.color = cc.Color.WHITE;
        }
    }

    // 判断此牌当前是否可以被使用
    isCardEnable(card:cc.Node){
        return true;
    }

    isCardUp(card:cc.Node){
        return (card.getComponent(Tag).tag&0xf00)>0;
    }

    setCardEnable(card:cc.Node,enable:boolean){
        //TODO
    }

    setCardUp(card:cc.Node,up:boolean){
        if(this.isCardUp(card) != up && card.active){
            this.runUpAction(card,up);
        }
    }

    runUpAction(card:cc.Node,up:boolean){
        if(up){
            card.getComponent(Tag).tag = (card.getComponent(Tag).tag|0xf00);
            card.stopAllActions();
            card.runAction(cc.moveTo(0.1,cc.v2(card.x,card.height / 6.0)))
        }else{
            card.getComponent(Tag).tag = (card.getComponent(Tag).tag&0x0ff);
            card.stopAllActions();
            card.runAction(cc.moveTo(0.1,cc.v2(card.x,0)))
        }
    }

    touchTest(p:cc.Vec2){
        for(let i=this.cards.length-1;i>=0;i--){
            let card = this.cards[i];
            if(card.active && card.getBoundingBoxToWorld().contains(p)){
                return card;
            }
        }
        return null;
    }

    reverseCardUp(card:cc.Node){
        this.setCardUp(card,!this.isCardUp(card));
    }

    clearAllCardUp(){
        if(this.isTakeFirst) return;
        for(let i=0;i<this.cards.length;i++){
            let n = this.cards[i];
            if(this.isCardUp(n) && n.active){
                this.runUpAction(n,false);
            }
        }
        this.node.emit(PlayCardEvent.ON_CLEAR_ALL_CARD_UP);
    }

    private touchCards(startCard:cc.Node,endCard:cc.Node){
        let began = false;
        for(let i=0;i<this.cards.length;i++){
            let n = this.cards[i];
            if (!n.active) continue;
            if (n == startCard || n == endCard) {
                if (began) {
                    this.setCardsHighlighted(n, true);
                    began = false;
                }
                else {
                    this.setCardsHighlighted(n, true);
                    began = true;
                    if (startCard == endCard) began = false;
                }
            }
            else
            {
                if (began){
                    this.setCardsHighlighted(n, true);
                }
                else{
                    this.setCardsHighlighted(n, false);
                }
            }
        }
    }


    private changeUpCards(startCard:cc.Node,endCard:cc.Node){
        let began = false;
        for(let i=0;i<this.cards.length;i++){
            let n = this.cards[i];
            if (!n.active) continue;
            if (n == startCard || n == endCard) {
                if (began) {
                    this.reverseCardUp(n);
                    began = false;
                    break;
                }
                else {
                    this.reverseCardUp(n);
                    began = true;
                    if (startCard == endCard) began = false;
                }
            }
            else
            {
                if (began) this.reverseCardUp(n);
            }
        }
    }

    private onTouchStart(event:cc.Touch){
        if (this.isTakeFirst) return;
        let card = this.touchTest(event.getLocation())
        if(card != null){
            if (this.isCardEnable(card)){
                this.touchStartCard = card;
                this.touchEndCard = card;
                this.isTouching = true;
                this.touchCards(this.touchStartCard,this.touchEndCard);
            }
        }else{
            if (this.isAutoDownCard)
            {
                this.clearAllCardUp();
            }
        }
    }

    private onTouchMove(event:cc.Touch){
        if (this.isTakeFirst) return;
        if(this.isTouching){
            let card = this.touchTest(event.getLocation())
            if(card != null){
                if (this.isCardEnable(card)){
                    this.touchEndCard = card;
                    this.touchCards(this.touchStartCard,this.touchEndCard);
                }
            }
        }
    }

    private onTouchEnd(event:cc.Touch){
        if (this.isTakeFirst) return;
        if(this.isTouching){
            this.touchCards(null,null);
            this.changeUpCards(this.touchStartCard,this.touchEndCard);
            if (this.touchStartCard == this.touchEndCard){
                this.node.emit(PlayCardEvent.ON_SELECTED_CARD);
            }
            else{
                this.node.emit(PlayCardEvent.ON_FRAME_SELECTED_CARD);
            }
            this.isTouching = false;
        }
    }
}